#pragma once
#include <cstddef>
#include <limits>
#include <stdexcept>
#include <vector>
#include <memory>
#include <type_traits>
#include <algorithm>
#include <atomic>


template <typename T>
class MultiBufferManager {
    static_assert(std::is_arithmetic_v<T>, "T must be a numeric type.");

public:
    MultiBufferManager(size_t buffer_size, size_t buffer_count)
        : buffer_size_(buffer_size), buffer_count_(buffer_count),
          buffers_(buffer_count, std::vector<T>(buffer_size)),
          write_positions_(buffer_count, 0),
          read_index_(0), write_index_(0), filled_count_(0)
    {
        // 内存已经在 vector 初始化时预分配
    }

    bool write(T value);
    bool read(T* out_buffer, const size_t step = 1);

    size_t availableBuffers() const noexcept {
        return buffer_count_ - filled_count_;
    }


private:
    size_t buffer_size_;
    size_t buffer_count_;
    std::vector<std::vector<T>> buffers_;
    std::vector<size_t> write_positions_;
    size_t read_index_;
    size_t write_index_;
    size_t filled_count_;
};

template <typename T>
bool MultiBufferManager<T>::write(T value) {
    if (filled_count_ == buffer_count_) return false; // 全部满了

    auto &buf = buffers_[write_index_];
    auto &pos = write_positions_[write_index_];

    buf[pos++] = value; // 写入数据

    if (pos == buffer_size_) {
        // 缓冲区写满
        pos = buffer_size_; // 明确标记满
        filled_count_++;
        // 切换到下一个可写缓冲区
        write_index_ = (write_index_ + 1) % buffer_count_;
        // 跳过那些已经写满的缓冲区
        size_t tries = 0;
        while (write_positions_[write_index_] == buffer_size_ && tries++ < buffer_count_) {
            write_index_ = (write_index_ + 1) % buffer_count_;
        }
    }

    return true;
}

template <typename T>
bool MultiBufferManager<T>::read(T* out_buffer, const size_t step) {
    if (filled_count_ == 0) return false; // 没有满的缓冲区可读

    auto &buf = buffers_[read_index_];
    auto &pos = write_positions_[read_index_];

    if (pos < buffer_size_) return false; // 当前未写满

    // 拷贝出整个缓冲区
    for (size_t i = 0; i < buffer_size_; ++i) {
        out_buffer[i * step] = buf[i];
    }

    // 复位该缓冲区
    pos = 0;
    filled_count_--;

    // 移动读索引
    read_index_ = (read_index_ + 1) % buffer_count_;

    return true;
}
